package gui.reports.removed;

import java.io.IOException;
import java.util.Calendar;
import java.util.GregorianCalendar;

import common.TimeSource;
import common.util.DateUtils;

import core.ProductManager;
import core.exception.SaveException;
import core.reports.HTMLBuilder;
import core.reports.IReportBuilder;
import core.reports.IReportVisitor;
import core.reports.PDFBuilder;
import core.reports.RemovedItemsVisitor;
import core.reports.ReportData;
import gui.common.*;

/**
 * Controller class for the removed items report view.
 */
public class RemovedReportController extends Controller implements
		IRemovedReportController {

	/**
	 * Constructor.
	 * 
	 * @param view Reference to the removed items report view
	 */
	public RemovedReportController(IView view) {
		super(view);

		construct();
	}

	//
	// Controller overrides
	//

	/**
	 * Returns a reference to the view for this controller.
	 * 
	 * {@pre None}
	 * 
	 * {@post Returns a reference to the view for this controller.}
	 */
	@Override
	protected IRemovedReportView getView() {
		return (IRemovedReportView) super.getView();
	}

	/**
	 * Sets the enable/disable state of all components in the controller's view.
	 * A component should be enabled only if the user is currently
	 * allowed to interact with that component.
	 * 
	 * {@pre None}
	 * 
	 * {@post The enable/disable state of all components in the controller's view
	 * have been set appropriately.}
	 */
	@Override
	protected void enableComponents() {
		Calendar lastRan = ReportData.instance().getRemovedItemsRan();
		IRemovedReportView view = getView();
		if (lastRan == null)
		{
			view.enableSinceLast(false);
			view.enableSinceDateValue(true);
		}
		else
		{
			view.enableSinceLast(true);
			view.enableSinceDateValue(false);
		}
		view.enableFormat(true);
		view.enableOK(true);
		view.enableSinceDate(true);
	}

	/**
	 * Loads data into the controller's view.
	 * 
	 *  {@pre None}
	 *  
	 *  {@post The controller has loaded data into its view}
	 */
	@Override
	protected void loadValues() {
		Calendar lastRan = ReportData.instance().getRemovedItemsRan();
		IRemovedReportView view = getView();
		if (lastRan == null)
		{
			view.setSinceLast(false);
			view.setSinceDate(true);
		}
		else
		{
			view.setSinceLastValue(lastRan.getTime());
			view.setSinceLast(true);
			view.setSinceDate(false);
		}
	}

	//
	// IExpiredReportController overrides
	//

	/**
	 * This method is called when any of the fields in the
	 * removed items report view is changed by the user.
	 */
	@Override
	public void valuesChanged() {
		if (getView().getSinceDate())
		{
			getView().enableSinceDateValue(true);
		}
		else
		{
			getView().enableSinceDateValue(false);
		}
	}

	/**
	 * This method is called when the user clicks the "OK"
	 * button in the removed items report view.
	 */
	@Override
	public void display() {
		IReportBuilder builder;
		
		//get the date
		Calendar date = TimeSource.instance().getTime();
		if (getView().getSinceDate())
		{
			date.setTime(getView().getSinceDateValue());
		}
		else
		{
			date = ReportData.instance().getRemovedItemsRan();
		}
		
		//get the output type, construct the proper builder
		FileFormat format = getView().getFormat();
		String title = "Items Removed Since " + DateUtils.formatDateTime(date.getTime());
		try {
			if (format == FileFormat.HTML) {
				builder = new HTMLBuilder(generateFilename(".html"), title);
			}
			else {
				builder = new PDFBuilder(generateFilename(".pdf"), title);
			}
		}
		catch (IOException e) {
			getView().displayErrorMessage("Cannot open a file to write to!");
			return;
		}
		
		//construct the visitor
		IReportVisitor visitor;
		try
		{
			visitor = new RemovedItemsVisitor(builder, date);
			ProductManager.instance().accept(visitor);
			builder.print();
		}
		catch (IOException e)
		{
			getView().displayErrorMessage("Cannot open a file to write to!");
		}
		
		date = TimeSource.instance().getTime();
		try {
			ReportData.instance().setRemovedItemsRan(date);
		} 
		catch (SaveException e) {
			e.printStackTrace();
			getView().displayErrorMessage("Save Exception: " + e.getMessage());
		}
	}

	private String generateFilename(String extension) {
		StringBuilder dateBuilder = new StringBuilder();
		dateBuilder.append("RemovedItems");
		dateBuilder.append(Calendar.getInstance().get(GregorianCalendar.MONTH));
		dateBuilder.append(Calendar.getInstance().get(GregorianCalendar.DAY_OF_MONTH));
		dateBuilder.append(Calendar.getInstance().get(GregorianCalendar.YEAR));
		dateBuilder.append(Calendar.getInstance().get(GregorianCalendar.HOUR));
		dateBuilder.append(Calendar.getInstance().get(GregorianCalendar.MINUTE));
		dateBuilder.append(Calendar.getInstance().get(GregorianCalendar.SECOND));
		dateBuilder.append(extension);
		return dateBuilder.toString();
	}
}

